package com.dainel.snake;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

/**
 * 详细说明
 *
 * @author Daniel
 * @version V1.0
 * @date 2020/5/13 10:07
 */
public class GamePanel extends JPanel implements KeyListener, ActionListener {
	// 蛇的长度
	int length;
	// 蛇的坐标
	int[] snakeX = new int[600];
	int[] snakeY = new int[500];
	// 方向
	DirectionEnum direction;
	// 游戏是否开启
	boolean isStart = false;
	// 游戏是否结束
	boolean isFail = false;
	// 定时器
	Timer timer = new Timer(100, this);
	// 食物的坐标
	int foodx;
	int foody;
	// 生成食物的随机数
	Random random = new Random();
	// 积分
	int score = 0;

	/**
	 * 构造器
	 */
	public GamePanel() {
		init();
		// 获取键盘的监听事件
		this.setFocusable(true);
		this.addKeyListener(this);
		// 开启定时器
		timer.start();
	}

	/**
	 * 初始化蛇的长度和位置
	 */
	public void init() {
		length = 3;
		for (int i = 0; i < length; i++) {
			snakeY[i] = 100;
			snakeX[i] = 100 - i * 25;
		}
		direction = DirectionEnum.R;

		randomFood();
	}

	@Override
	protected void paintComponent(Graphics g) {
		// 清屏
		super.paintComponent(g);
		// 设置背景颜色
		this.setBackground(Color.WHITE);
		// 绘制头部广告栏
		Data.header.paintIcon(this, g, 25, 15);
		// 绘制游戏区域
		g.fillRect(25, 75, 850, 600);

		// 开始绘制蛇第一次出现的位置
		if (direction == DirectionEnum.R) {
			Data.right.paintIcon(this, g, snakeX[0], snakeY[0]);
		} else if (direction == DirectionEnum.L) {
			Data.left.paintIcon(this, g, snakeX[0], snakeY[0]);
		} else if (direction == DirectionEnum.U) {
			Data.up.paintIcon(this, g, snakeX[0], snakeY[0]);
		} else if (direction == DirectionEnum.D) {
			Data.down.paintIcon(this, g, snakeX[0], snakeY[0]);
		}
		for (int i = 1; i < length; i++) {
			Data.body.paintIcon(this, g, snakeX[i], snakeY[i]);
		}

		// 绘制积分
		g.setColor(Color.WHITE);
		g.setFont(new Font("微软雅黑", Font.BOLD, 18));
		g.drawString("长度：" + length, 750, 35);
		g.drawString("积分：" + score, 750, 60);

		// 绘制食物
		Data.food.paintIcon(this, g, foodx, foody);

		// 提示：是否开始游侠
		if (!isStart) {
			g.setColor(Color.WHITE);
			g.setFont(new Font("微软雅黑", Font.BOLD, 40));
			g.drawString("按下空格开始游戏", 300, 300);
		}
		if (isFail) {
			g.setColor(Color.RED);
			g.setFont(new Font("微软雅黑", Font.BOLD, 40));
			g.drawString("游戏结束，按下空格重新开始", 200, 300);
		}
	}


	/**
	 * 监听键盘的输入
	 *
	 * @param keyEvent
	 */
	@Override
	public void keyPressed(KeyEvent keyEvent) {
		// 获取按下的键位
		int keyCode = keyEvent.getKeyCode();
		// 判断键位是开始暂替或者方向
		if (keyCode == KeyEvent.VK_SPACE) {
			if (isFail) {
				isFail = false;
				init();
			} else {
				isStart = !isStart;
			}

			// 刷新界面
			repaint();
		} else if (keyCode == KeyEvent.VK_UP) {
			direction = DirectionEnum.U;
		} else if (keyCode == KeyEvent.VK_DOWN) {
			direction = DirectionEnum.D;
		} else if (keyCode == KeyEvent.VK_LEFT) {
			direction = DirectionEnum.L;
		} else if (keyCode == KeyEvent.VK_RIGHT) {
			direction = DirectionEnum.R;
		}
	}

	/**
	 * 定时器监听，执行定时操作
	 *
	 * @param actionEvent
	 */
	@Override
	public void actionPerformed(ActionEvent actionEvent) {
		// 如果处于开始状态
		if (isStart && !isFail) {
			// 执行身体部分的移动
			// 后一个替补前一个坐标
			for (int i = length - 1; i > 0; i--) {
				snakeX[i] = snakeX[i - 1];
				snakeY[i] = snakeY[i - 1];
			}
			// 根据方向键控制头部的移动
			if (direction == DirectionEnum.R) {
				snakeX[0] = snakeX[0] + 25;
				// 右边界判断
				if (snakeX[0] > 850) {
					snakeX[0] = 25;
				}
			} else if (direction == DirectionEnum.L) {
				snakeX[0] = snakeX[0] - 25;
				// 左边界判断
				if (snakeX[0] < 25) {
					snakeX[0] = 850;
				}
			} else if (direction == DirectionEnum.U) {
				snakeY[0] = snakeY[0] - 25;
				// 上边界判断
				if (snakeY[0] < 75) {
					snakeY[0] = 650;
				}
			} else if (direction == DirectionEnum.D) {
				snakeY[0] = snakeY[0] + 25;
				// 下边界判断
				if (snakeY[0] > 650) {
					snakeY[0] = 75;
				}
			}

			if (snakeX[0] == foodx && snakeY[0] == foody) {
				length += 1;
				score += 10;
				randomFood();
			}

			// 结束判断
			for (int i = 1; i < length; i++) {
				if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {
					isFail = true;
				}
			}

			// 刷新界面
			repaint();
		}
		// 开启定时器
		timer.start();
	}

	/**
	 * 随机生成食物
	 */
	private void randomFood() {
		foodx = 25 + 25 * random.nextInt(34);
		foody = 75 + 25 * random.nextInt(24);
	}

	@Override
	public void keyTyped(KeyEvent keyEvent) {

	}

	@Override
	public void keyReleased(KeyEvent keyEvent) {

	}


}
